import { DbService } from '@app/db';
import { DeviceParamsRule } from '@app/db/entities/DeviceParamsRule';
import { Body, Controller, Delete, Get, Param, ParseIntPipe, Post, Put, Req } from '@nestjs/common';
import { FindOptionsWhere, Like } from 'typeorm';
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
import { BaseController } from '../base/base.controller';
import { DtoPipe } from '../pipes/dto/dto.pipe';
import { PageDto, AddDto, UpdateDto } from './dto';

@Controller('deviceParamsRule')
export class DeviceParamsRuleController extends BaseController {
    constructor(
        private readonly db:DbService
    ){
        super()
    }

    @Get('options')
    async options(@Req() { userId }) {
        return this.successRes(await this.db.deviceParamsRule.find({ownerId : userId}, {id : true, name : true}))
    }


    @Post('page')
    async page(@Body() dto:PageDto, @Req() { userId }) {
       
        let result:PaginationResult<DeviceParamsRule> = {
            total : 0,
            rows : []
        }

        let where:FindOptionsWhere<DeviceParamsRule> = {
            ownerId : userId
        }

        if(dto.name) {
            where.name = Like(`%${dto.name}%`)
        }

        result.total = await this.db.deviceParamsRule.count(where)

        if(result.total > 0) {
            result.rows = await this.db.deviceParamsRule.pagination(dto.pageNo, dto.pageSize, where, null, {id : 'DESC'})
        }
        

        return this.successRes(result)

    }

    @Post('add')
    async add(@Body(new DtoPipe({skipMissingProperties : false})) dto:AddDto, @Req() { userId }) {


        const data:QueryDeepPartialEntity<DeviceParamsRule> = {
            name : dto.name,
            ownerId : userId,
            createTime : this.utils.time(),
        }

        if(dto.params) {
            data.params = dto.params
        }

    
        if(dto.remark) {
            data.remark = dto.remark
        }

        const res = await this.db.deviceParamsRule.insert(data)
        return res ? this.successRes() : this.failRes()
    }

    @Put('update/:id')
    async update(@Body(new DtoPipe({skipNullProperties : true})) dto:UpdateDto, @Param('id', ParseIntPipe) id:number, @Req() { locale }) {
        if(id <= 0) return


        let fields = Object.keys(dto) as (keyof DeviceParamsRule)[]
        if(fields.length == 0) return
        

        const row = await this.db.deviceParamsRule.findOne({id : id}, fields)
        if(!row) return

        let updateData:KeyToValueType<DeviceParamsRule> = {}
        for(let k in row) {
            if(k in dto && row[k] != dto[k]) {
                updateData[k] = dto[k]
            }
        }


        if(Object.keys(updateData).length == 0) return this.successRes()

        

        updateData.updateTime = this.utils.time()


        const res = await this.db.deviceParamsRule.update({id : id}, updateData)
        return res === 0 ? this.failRes() : this.successRes()
    }


    @Delete('delete/:id')
    async delete(@Param('id', ParseIntPipe) id:number) {
        if(id <= 0) return
        const res = await this.db.deviceParamsRule.delete({id : id})
        return res === 0 ? this.failRes() : this.successRes()
    }
}
